// 二次封装axios
// 1.axios配置
import router from '@/router'
import { useUserStore } from '@/stores'
import axios, { type Method } from 'axios'
import { showFailToast } from 'vant'
// 1.1 创建一个请求基地址
// 1.2 添加请求拦截器 在请求头携带token
// 1.3 添加响应拦截器 401错误拦截去登录页面 判断业务是否成功 剥离无效的数据
// export const baseURL = 'https://consult-api.itheima.net/'  //为将来做准备，比如写一些聊天的功能等等，需要这个基地址
const baseURL = 'https://consult-api.itheima.net/' 
const instance = axios.create({
    baseURL,
    timeout: 10000
}) 

instance.interceptors.request.use(config => {
    // 修改config  比如修改请求头

    // 获取token 也就是user的状态仓库
    const store = useUserStore()
    if (store.user?.token && config.headers) {  //判断 如果有这个变量，才会执行以下代码
        config.headers['Authorization'] = `Bearer ${store.user?.token}`
    }
    return config
},
    (err) => Promise.reject(err)  //当请求失败的时候，返回一个promise，告诉对方报错的提示
)

// 响应
instance.interceptors.response.use(res => {
    // status 是200是响应成功的 res.data.code 是10000业务横杠
    // 那么如果res.data.code不是10000 使用vant轻提示 提示用户
    if (res.data.code !== 10000) {
        showFailToast(res.data?.message || '网络错误')
        // 当错误时，将res.data传入
        return Promise.reject(res.data)
    }
    return res.data  //剥离无效数据
}, err => {
    // 请求报错 响应出错
    // 401错误拦截去登录页面
    // 两种情况判断：
    // 1.现在在 /user/patient 页面下，发起一个获取用户信息的请求，但是此时token失效
    // 2.跳转登录页面，登录成功之后，需要跳转回 /user 页面 (默认跳转 /user 首页)
    if (err.response.status === 401) {
        // 删除用户信息
        const store = useUserStore()
        store.delUser()
        // 传入完整路径 不带查询参数
        router.push(`/login?returnUrl=?=${router.currentRoute.value.fullPath}`)  //跳转到登录页 并携带标识
    }
    return Promise.reject(err)
})

// 2.请求工具函数
// 1.1 参数传递 url method 和 submitData
// 1.2 返回一个 axios调用接口的promise对象
// const request = (url: string, method: string, submitData: object) => {
//     return instance.request({
//         url,
//         method,
//         // 区分get和其他请求 例如 post 或者put
//         // 当get请求提交数据 选项 params
//         // 当post请求 选项为 data
//         [ method.toLowerCase() === 'get' ? 'params' : 'data' ]: submitData
//     })
// }

// 设置自定义响应数据类型
type Data<T> = {
    success: boolean
    code: string
    message: string
    data: T
}

// Method类型是axios提供的ts类型声明文件
const request = <T>(url: string, method: Method = 'get', submitData?: object) => {
    // 泛型的第二个参数 可以自定义响应数据类型
    return instance.request<T, Data<T>>({
        url,
        method,
        // 区分get和其他请求 例如 post 或者put
        // 当get请求提交数据 选项 params
        // 当post请求 选项为 data
        [ method.toLowerCase() === 'get' ? 'params' : 'data' ]: submitData
    })
}

// 导出配置好的axios和公共baseURL
export { baseURL, instance, request}
